#include "QueryParserTest.h"

#if _DEBUG

#include <cppunit/config/SourcePrefix.h>

bool AreQueryTreesEqual( query_tree& left, query_tree& right )
{
	if ( left.variables.size() != right.variables.size() )
		return false;

	if ( left.targets.size() != right.targets.size() )
		return false;

	if ( left.relations.size() != right.relations.size() )
		return false;

	for ( int i = 0; i < left.variables.size(); i++ )
	{
		query_declaration l = left.variables[ i ];
		query_declaration r = right.variables[ i ];
		if ( ( l.name.compare( r.name ) != 0 ) || ( l.type != r.type ) )
			return false;
	}

	for ( int i = 0; i < left.targets.size(); i++ )
	{
		query_parameter l = left.targets[ i ];
		query_parameter r = right.targets[ i ];
		if ( ( l.value.compare( r.value ) != 0 ) || ( l.type != r.type ) )
			return false;
	}

	for ( int i = 0; i < left.relations.size(); i++ )
	{
		query_relation l = left.relations[ i ];
		query_relation r = right.relations[ i ];

		if ( l.parameters.size() != r.parameters.size() )
			return false;

		for ( int j = 0; j < l.parameters.size(); j++ )
		{
			query_parameter lp = l.parameters[ j ];
			query_parameter rp = r.parameters[ j ];

			if ( ( lp.value.compare( rp.value ) != 0 ) || ( lp.type != rp.type ) )
				return false;
		}
	}
	
	return true;
}

query_declaration MakeVariable( EntityType type, std::string name )
{
	query_declaration d;
	d.type = type;
	d.name = name;
	return d;
}


query_parameter MakeParameter( ParameterType type, std::string value )
{
	query_parameter p;
	p.type = type;
	p.value = value;
	return p;
}

query_relation MakeRelation( RelationType type, query_parameter p1, query_parameter p2 )
{
	query_relation r;
	r.type = type;
	r.parameters.push_back( p1 );
	r.parameters.push_back( p2 );
	return r;
}

query_relation MakeRelation( RelationType type, query_parameter p1, query_parameter p2, query_parameter p3 )
{
	query_relation r;
	r.type = type;
	r.parameters.push_back( p1 );
	r.parameters.push_back( p2 );
	r.parameters.push_back( p3 );
	return r;
}

query_relation MakeRelation( RelationType type, query_parameter p1, query_parameter p2, query_parameter p3, query_parameter p4 )
{
	query_relation r;
	r.type = type;
	r.parameters.push_back( p1 );
	r.parameters.push_back( p2 );
	r.parameters.push_back( p3 );
	r.parameters.push_back( p4 );
	return r;
}

void PrintQueryTree( query_tree& tree )
{
	std::cout << "variables:\n";
	for( auto variable = tree.variables.begin(); variable != tree.variables.end(); variable++ )
	{
		std::cout << "type: " << variable->type << ", name: " << variable->name << std::endl;
	}

	std::cout << "targets:\n";
	for( auto target = tree.targets.begin(); target != tree.targets.end(); target++ )
	{
		std::cout << "type: " << target->type << ", value: " << target->value << std::endl;
	}

	std::cout << "relations:\n";
	for( auto relation = tree.relations.begin(); relation != tree.relations.end(); relation++ )
	{
		std::cout << "type: " << relation->type << ", parameters: \n";
		for ( auto parameter = relation->parameters.begin(); parameter != relation->parameters.end(); parameter++ )
		{
			std::cout << "type: " << parameter->type << ", value: " << parameter->value << std::endl;
		}
		std::cout << "\n\n";
	}
	std::cout << "\n\n";
}

void QueryParserTest::setUp()
{
	// underscore
	any.type = ANY;
	any.value = "_";

	// boolean
	boolean.type = BOOL;
	boolean.value = "BOOLEAN";

	// variable
	v.type = v1.type = v2.type = kVARIABLE;
	v.name = "v";
	v1.name = "v1";
	v2.name = "v2";

	// prog_line
	p.type = p1.type = p2.type = kPROG_LINE;
	p.name = "p";
	p1.name = "p1";
	p2.name = "p2";

	// stmt
	s.type = s1.type = s2.type = kSTMT;
	s.name = "s";
	s1.name = "s1";
	s2.name = "s2";

	// assign
	a.type = a1.type = a2.type = kASSIGN;
	a.name = "a";
	a1.name = "a1";
	a2.name = "a2";

	// call
	c.type = c1.type = c2.type = kCALL;
	c.name = "c";
	c1.name = "c1";
	c2.name = "c2";

	// procedure
	pr.type = pr1.type = pr2.type = kPROCEDURE;
	pr.name = "pr";
	pr1.name = "pr1";
	pr2.name = "pr2";

	// if
	i.type = i1.type = i2.type = kIF;
	i.name = "i";
	i1.name = "i1";
	i2.name = "i2";

	// while
	w.type = w1.type = w2.type = kWHILE;
	w.name = "w";
	w1.name = "w1";
	w2.name = "w2";

	// constant
	cn.type = cn1.type = cn2.type = kCONSTANT;
	cn.name = "cn";
	cn1.name = "cn1";
	cn2.name = "cn2";

	// relations
	with.type = WITH;
	modifies.type = MODIFIES;
	uses.type = USES;
	calls.type = CALLS; calls_t.type = CALLS_T;
	parent.type = PARENT; parent_t.type = PARENT_T;
	follows.type = FOLLOWS; follows_t.type = FOLLOWS_T;
	next.type = NEXT; next_t.type = NEXT_T; nextbip.type = NEXTBIP; nextbip_t.type = NEXTBIP_T;
	affects.type = AFFECTS; affects_t.type = AFFECTS_T; affectsbip.type = AFFECTSBIP; affectsbip_t.type = AFFECTSBIP_T;
	pattern.type = PATTERN;
	sibling.type = SIBLING;

}

void QueryParserTest::tearDown()
{
}

CPPUNIT_TEST_SUITE_REGISTRATION( QueryParserTest );

void QueryParserTest::test1()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( v );
	handcrafted.variables.push_back( v1 );
	handcrafted.variables.push_back( v2 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "v" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "variable v; variable v1, v2; Select v", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test2()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( p2 );
	handcrafted.variables.push_back( p );
	handcrafted.variables.push_back( p1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "p2" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "prog_line p2, p, p1;    Select p2", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test3()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s1" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s2; stmt s1; select s1", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test4()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s1" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s2; stmt s1; select <s,s1>", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test5()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( c );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "c" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "call c  ;   select c", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test6()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a );
	handcrafted.variables.push_back( a1 );
	handcrafted.variables.push_back( a2 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a2" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a; assign a1; assign a2; select <a2    ,a>", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test7()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( i1 );
	handcrafted.variables.push_back( i );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "i1" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "i" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "if i1, i ; SELECT <i1,         i>", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test8()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( pr2 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "pr2" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "procedure pr2 ; sELecT pr2", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test9()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( w );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "w" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "while w ; sELeCT w", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test10()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( cn2 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "cn2" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "constant cn2 ; selecT cn2", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test11()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a1 );
	handcrafted.variables.push_back( a2 );
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( c2 );
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( i );
	handcrafted.variables.push_back( w );
	handcrafted.variables.push_back( i1 );
	handcrafted.variables.push_back( cn );
	handcrafted.variables.push_back( w2 );
	handcrafted.variables.push_back( pr1 );
	handcrafted.variables.push_back( pr2 );
	handcrafted.variables.push_back( p );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a2" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a1,a2; stmt s2; call c2; stmt s; if i; while w; if i1; constant cn ; while w2; procedure pr1,pr2; prog_line     p; SeLecT a2", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test12()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a1 );
	handcrafted.variables.push_back( a2 );
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( c2 );
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( i );
	handcrafted.variables.push_back( w );
	handcrafted.variables.push_back( i1 );
	handcrafted.variables.push_back( cn );
	handcrafted.variables.push_back( w2 );
	handcrafted.variables.push_back( pr1 );
	handcrafted.variables.push_back( pr2 );
	handcrafted.variables.push_back( p );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a2" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "pr1" ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a1,a2; stmt s2; call c2; stmt s; if i; while w; if i1; constant cn ; while w2; procedure pr1,pr2; prog_line     p; SeLecT <a2,  s    ,pr1>", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test13()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( v2 );
	handcrafted.variables.push_back( pr1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "v2" ) );
	handcrafted.relations.push_back( MakeRelation( USES, MakeParameter( ENTITY, "p1" ),  MakeParameter( ENTITY, "v2" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "variable v2;    procedure pr1 ; selecT v2 suCH thAt USes(p1,v2   )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test14()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( v2 );
	handcrafted.variables.push_back( s );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( USES, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "v2" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "variable v2;    stmt s ; selecT s SUCH that UsEs(s,v2   )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test15()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( v2 );
	handcrafted.variables.push_back( pr1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "v2" ) );
	handcrafted.relations.push_back( MakeRelation( MODIFIES, MakeParameter( ENTITY, "p1" ),  MakeParameter( ENTITY, "v2" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "variable v2;    procedure pr1 ; selecT v2 such that MODIfies(p1,v2   )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test16()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( v2 );
	handcrafted.variables.push_back( s );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( MODIFIES, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "v2" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "variable v2;    stmt s ; selecT s such that mOdifIes(s,v2   )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test17()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( pr1 );
	handcrafted.variables.push_back( pr );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "pr" ) );
	handcrafted.relations.push_back( MakeRelation( CALLS, MakeParameter( ENTITY, "pr" ),  MakeParameter( ENTITY, "pr1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "procedure pr1, pr; SELECT pr such tHaT Calls(  pr,  pr1   )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test18()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( pr1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "pr1" ) );
	handcrafted.relations.push_back( MakeRelation( CALLS_T, any,  MakeParameter( ENTITY, "pr1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "procedure pr1; SELECT pr1 such tHaT Calls*(  _ ,  pr1   )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test19()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( PARENT, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "s1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s1; SELECT s SucH tHaT Parent(  s ,  s1      )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test20()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( PARENT_T, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "s1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s1; SELECT s SucH tHaT Parent*(  s ,  s1      )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test21()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( FOLLOWS, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "s1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s1; SELECT s SucH tHaT Parent*(  s ,  s1      )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test22()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( FOLLOWS_T, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "s1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s1; SELECT s SucH tHaT fOlLoWs*(  s ,  s1      )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test23()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( NEXT, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "s1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s1; SELECT s SucH tHaT Next(  s ,  s1      )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test24()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( NEXT_T, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "s1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s1; SELECT s SucH tHaT Next*(  s ,  s1      )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test25()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( NEXTBIP, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "s1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s1; SELECT s SucH tHaT NextBip(  s ,  s1      )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test26()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s" ) );
	handcrafted.relations.push_back( MakeRelation( NEXTBIP_T, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "s1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s, s1; SELECT s SucH tHaT nExTbip*(  s ,  s1      )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test27()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a );
	handcrafted.variables.push_back( a1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a1" ) );
	handcrafted.relations.push_back( MakeRelation( AFFECTS, MakeParameter( ENTITY, "a1" ),  MakeParameter( ENTITY, "a" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a; assign a1; SELECT <a,a1  >  SucH tHaT affecTs(    a1 ,a)", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test28()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a );
	handcrafted.variables.push_back( a1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a1" ) );
	handcrafted.relations.push_back( MakeRelation( AFFECTS_T, MakeParameter( ENTITY, "a1" ),  MakeParameter( ENTITY, "a" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a; assign a1; SELECT <a,a1  >  SucH tHaT affecTs*(    a1 ,a)", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test29()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a );
	handcrafted.variables.push_back( a1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a1" ) );
	handcrafted.relations.push_back( MakeRelation( AFFECTSBIP, MakeParameter( ENTITY, "a1" ),  MakeParameter( ENTITY, "a" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a; assign a1; SELECT <a,a1  >  SucH tHaT AFFECTSBIP(    a1 ,a)", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test30()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a );
	handcrafted.variables.push_back( a1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a1" ) );
	handcrafted.relations.push_back( MakeRelation( AFFECTSBIP_T, MakeParameter( ENTITY, "a1" ),  MakeParameter( ENTITY, "a" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a; assign a1; SELECT <a,a1  >  SucH tHaT aFFecTsBiP*(    a1 ,a)", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test31()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s2" ) );
	handcrafted.relations.push_back( MakeRelation( SIBLING, MakeParameter( ENTITY, "s1" ),  MakeParameter( ENTITY, "s2" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s2, s1; SEleCT   s2  SucH tHaT siblinG(    s1 ,s2)", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test32()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s2" ) );
	handcrafted.relations.push_back( MakeRelation( NEXTBIP_T, MakeParameter( ENTITY, "s" ),  MakeParameter( ENTITY, "s1" ) ) );
	handcrafted.relations.push_back( MakeRelation( SIBLING, MakeParameter( ENTITY, "s2" ),  MakeParameter( ENTITY, "s1" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s2; stmt s, s1; SELECT s2 SucH tHaT nExTbip*(  s ,  s1      ) and siblIng( s2, s1 )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test33()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( s1 );
	handcrafted.targets.push_back( boolean );
	handcrafted.relations.push_back( MakeRelation( NEXTBIP_T, MakeParameter( ENTITY, "s" ),  any ) );
	handcrafted.relations.push_back( MakeRelation( SIBLING, MakeParameter( ENTITY, "s2" ),  MakeParameter( ENTITY, "s1" ) ) );
	handcrafted.relations.push_back( MakeRelation( MODIFIES, MakeParameter( ENTITY, "s" ),  MakeParameter( NAME, "x" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s2; stmt s, s1; SELECT BOOLEAN SucH tHaT nExTbip*(  s ,  _) and siblIng( s2, s1  ) such THAT moDifies( s, \"x\")", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test34()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( cn1 );
	handcrafted.targets.push_back( boolean );
	handcrafted.relations.push_back( MakeRelation( WITH, MakeParameter( ATTRIBUTE, "s2.stmt#" ),  MakeParameter( ATTRIBUTE, "cn1.value" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s2; constant cn1; SELECT BOOLEAN with s2.stmt# = cn1.value", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test35()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( cn1 );
	handcrafted.targets.push_back( boolean );
	handcrafted.relations.push_back( MakeRelation( WITH, MakeParameter( ATTRIBUTE, "s2.stmt#" ),  MakeParameter( LINE, "99" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s2; constant cn1; SELECT BOOLEAN with s2.stmt# = 99", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test36()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( cn1 );
	handcrafted.targets.push_back( boolean );
	handcrafted.relations.push_back( MakeRelation( WITH, MakeParameter( ATTRIBUTE, "s2.stmt#" ),  MakeParameter( LINE, "99" ) ) );
	handcrafted.relations.push_back( MakeRelation( WITH, MakeParameter( ATTRIBUTE, "s2.stmt#" ),  MakeParameter( ATTRIBUTE, "cn1.value" ) ) );
	handcrafted.relations.push_back( MakeRelation( WITH, MakeParameter( ATTRIBUTE, "cn1.value" ),  MakeParameter( LINE, "3" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "stmt s2; constant cn1; SELECT BOOLEAN with s2.stmt# = 99 with s2.stmt# = cn1.value and cn1.value =  3", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test37()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a );
	handcrafted.targets.push_back( boolean );
	handcrafted.relations.push_back( MakeRelation( PATTERN, MakeParameter( ENTITY, "a" ),  MakeParameter( NAME, "y" ), any ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a; SELECT BOOLEAN pattern  a(\"y\", _ )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test38()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a );
	handcrafted.variables.push_back( i );
	handcrafted.targets.push_back( boolean );
	handcrafted.relations.push_back( MakeRelation( PATTERN, MakeParameter( ENTITY, "a" ),  MakeParameter( NAME, "y" ), any ) );
	handcrafted.relations.push_back( MakeRelation( PATTERN, MakeParameter( ENTITY, "i" ),  MakeParameter( NAME, "z" ), any, any ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a; if i; SELECT BOOLEAN pattern  a(\"y\", _ ) pattern i( \"z\", _, _ )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test39()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( a );
	handcrafted.variables.push_back( i );
	handcrafted.variables.push_back( w );
	handcrafted.variables.push_back( v );
	handcrafted.targets.push_back( boolean );
	handcrafted.relations.push_back( MakeRelation( PATTERN, MakeParameter( ENTITY, "a" ),  MakeParameter( NAME, "y" ), any ) );
	handcrafted.relations.push_back( MakeRelation( PATTERN, MakeParameter( ENTITY, "i" ),  MakeParameter( NAME, "z" ), any, any ) );
	handcrafted.relations.push_back( MakeRelation( PATTERN, MakeParameter( ENTITY, "w" ),  MakeParameter( ENTITY, "v" ), any ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "assign a; if i; while w; variable v; SELECT BOOLEAN pattern  a(\"y\", _ ) pattern i( \"z\", _, _ ) and w ( v, _ )", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

void QueryParserTest::test40()
{
	// HANDCRAFTED
	query_tree handcrafted;
	handcrafted.variables.push_back( p1 );
	handcrafted.variables.push_back( v2 );
	handcrafted.variables.push_back( a );
	handcrafted.variables.push_back( i );
	handcrafted.variables.push_back( w );
	handcrafted.variables.push_back( v );
	handcrafted.variables.push_back( s2 );
	handcrafted.variables.push_back( s1 );
	handcrafted.variables.push_back( s );
	handcrafted.variables.push_back( cn1 );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "a" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s2" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "s1" ) );
	handcrafted.targets.push_back( MakeParameter( ENTITY, "cn1" ) );
	handcrafted.relations.push_back( MakeRelation( MODIFIES, MakeParameter( ENTITY, "p1" ),  MakeParameter( ENTITY, "v2" ) ) );
	handcrafted.relations.push_back( MakeRelation( WITH, MakeParameter( ATTRIBUTE, "s2.stmt#" ),  MakeParameter( LINE, "99" ) ) );
	handcrafted.relations.push_back( MakeRelation( WITH, MakeParameter( ATTRIBUTE, "s2.stmt#" ),  MakeParameter( ATTRIBUTE, "cn1.value" ) ) );
	handcrafted.relations.push_back( MakeRelation( WITH, MakeParameter( ATTRIBUTE, "cn1.value" ),  MakeParameter( LINE, "3" ) ) );
	handcrafted.relations.push_back( MakeRelation( PATTERN, MakeParameter( ENTITY, "a" ),  MakeParameter( NAME, "y" ), any ) );
	handcrafted.relations.push_back( MakeRelation( PATTERN, MakeParameter( ENTITY, "i" ),  MakeParameter( NAME, "z" ), any, any ) );
	handcrafted.relations.push_back( MakeRelation( PATTERN, MakeParameter( ENTITY, "w" ),  MakeParameter( ENTITY, "v" ), any ) );
	handcrafted.relations.push_back( MakeRelation( NEXTBIP_T, MakeParameter( ENTITY, "s" ),  any ) );
	handcrafted.relations.push_back( MakeRelation( SIBLING, MakeParameter( ENTITY, "s2" ),  MakeParameter( ENTITY, "s1" ) ) );
	handcrafted.relations.push_back( MakeRelation( MODIFIES, MakeParameter( ENTITY, "s" ),  MakeParameter( NAME, "x" ) ) );
	// PARSED
	query_tree generated;
	_query_parser.Parse( "prog_line p1;variable   v2;assign a; if i; while w; variable v; stmt s2, s1, s; constant cn1; SELECT <a,  s2, s1, cn1> suCh THaT Modifies(p1, v2) with s2.stmt# =  99 and s2.stmt# = cn1.value with cn1.value = 3 pattern  a(\"y\", _ ) pattern i( \"z\", _, _ ) and w ( v, _ ) SucH tHaT nExTbip*(  s ,  _) and SIBLING( s2, s1  ) such THAT moDifies( s, \"x\")", generated );
	// COMPARE
	CPPUNIT_ASSERT( AreQueryTreesEqual( handcrafted, generated ) );
}

#endif